home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-08-10 | 59.6 KB | 2,187 lines |
- #!/bin/sh
- # to extract, remove the header and type "sh filename"
- if `test ! -d ./src`
- then
- mkdir ./src
- echo "mkdir ./src"
- fi
- if `test ! -s ./src/textyl.pas.aa`
- then
- echo "writing ./src/textyl.pas.aa"
- cat > ./src/textyl.pas.aa << 'E_O_F'
-
- (*$b0*)
-
- program tyldvidvi(input,output);
- (* ----------------------------------------------------------
- TeXtyl line-drawing interface for TeX.
- copyright (c) 1987 John S. Renner
- All rights reserved.
-
- ABSTRACT: TeXtyl reads in a DVI file, and processes 'specials'
- that refer to graphics capabilities that it knows about,
- like line, spline, ThickThinSpline, and musical
- beams and slurs. TeXtyl then outputs a new DVI file,
- with the special-macros expanded and converted to
- DVI-commands for character setting.
-
- DEPENDENCIES: Few assumptions about Pascal are assumed. All
- identifiers are unique to eight characters. There are
- notes to indicate system-dependencies.
- I assume the standard definition of "READ(fil, x)" to be
- equivalent to "x := fil^; GET(fil)" , and
- "WRITE(fil, x)" == "fil^ := x; PUT(fil)" .
- Arrays are passed by reference (VAR) for efficiency.
- See also the "sysdependent" procedure;
- Problem areas, or areas for expansion are marked with ###
-
- -------------------------------------------------------------*)
- (* Revision History:
- Jun. 1986 v1.0 Basic version of TeXtyl
- Dec. 1986 v1.1 Added adaptive subdivision for spline
- interpolation. Added Cardinal basis.
- Mar. 1987 v1.2 Added F and W flags for beginfigure
- to allow required and/or actual dimensions
- to interface with files output by the
- DP drawing program from Carnegie-Mellon
- also various fixes
- Apr. 1987 v1.3 Added linestyles (dotted, dashed, dotdashed)
-
- *)
-
- label
- 666, 30;
- (*=====================CONST============================*)
- #include "tylext.h"
- #include "texpaths.h"
-
- const
- TylVersion = 'This is TeXtyl, Version 1.30';
- (* for dvi-commands *)
- PUT1 = 133;
- SET1 = 128;
- PUTRULE = 137;
- NOP = 138;
- PUSH = 141;
- POP = 142;
- RIGHTLEFT = 143;
- DOWNUP = 157;
- FONTDEF = 244;
- USEFONT = 236;
- OURFONTFLAG = 256; (* our special 'byte' value flag *)
-
- USESTDAREA = 0; (* flag to use the 'standard' area to find .tfm files *)
-
- (* some conversions and numbers *)
- SPPERPT = 65536; (* scaled points per printers point *)
- SPPERMM = 186468; (* scaled pts per millimetre *)
-
- RADTODEG = 57.29577952; (* degrees per radian *)
- DEGTORAD = 0.0174532925; (* radians per degree *)
- PI = 3.141592654;
-
- TWO16 = 65536; (* 2 ^ 16 *)
- TWO20 = 1048576; (* 2 ^ 20 *)
- TWO23 = 8388608;
- TWO24 = 16777216;
- TWO27 = 134217728;
- TWO31 = 2147483647; (* 2^31 - 1 *)
-
- BIGREAL = 1.0e30;
- MAXVECLENsp = 262144; (* Normal maximum length of longest
- * vector-font character in scaled points
- *)
- (* Music Font dependent constants *)
- DOTCHAR = 127; (* ascii number of char that is a dot *)
- QNOTEGHUS = 18.0; (* MF: Global Horizontal Units for a Quarternote *)
- QNOTEGVUS = 16.0; (* MF: Global Vertical units for a quarternote *)
- GBMGHUS = 12.0; (* MF: horizontal units for a grace beam *)
- GBMGVUS = 9.0;
-
- BMSTART = 0; BMEND = 69; (* indices for start/end of the beam chars *)
- LOBM1 = 0; (* indices for the regular beam chars that *)
- HIBM1 = 34; (* are 1 quarternote long, and *)
- LOBM1p5 = 35; (* for those that are 1.5 quarternotes long *)
- HIBM1p5 = 69;
-
- GBMSTART = 70; GBMEND = 105; (* indices for the grace beams *)
- LOGBMp5 = 70; (* indices for grace beam chars that *)
- HIGBMp5 = 87; (* are 0.5 grace quarternote long, and *)
- LOGBMp66 = 88; (* 0.66 grace quarternotes long *)
- HIGBMp66 = 105;
-
- LoVThick = 1; (* Bounds for Vector char thicknesses *)
- HiVThick = 13;
-
- SizVFontTable = 39; (* size of the Vector Font Table *) { 3*HiVThick }
- SizMFontTable = 18;(* size of the Music Font Table *)
- MAXLABELFONTS = 5;
- SizLFontTable = MAXLABELFONTS; (* size of the Label Font Table *)
-
- MAXCTLPTS = 63; (* max number of control points *)
- MAXCTLPTSp3 = 66; (* max control points + 3 *)
- ARRLIMIT = 100; (* limit for strings and other arrays *)
- MAXSPLINESEGS = 480; (* max number of spline segments *)
- MAXOLEN = 128; (* max length of Ostring that holds bytes of dvi cmds *)
- MAXTBDs = 50; (* max number of Fonts-to-be-Defined *)
-
- MAXDVISTRINGS = 600; (* max number of DVI Ostrings per page *)
- TFMSIZE = 8000; (* size of TFM array to hold .tfm file info *)
-
- (* Numeric names for the TeXtyl primitives *)
- Aline = 1; (* should be first *)
- Aspline = 2;
- Attspline = 3;
- Abeam = 4;
- Atieslur = 5;
- Aarc = 6;
- Alabel = 7;
- Afigure = 8; (* should be last one *)
-
- MAXFONTS = 60; (* number of TeX fonts to keep track of *)
- STACKSIZE = 50; (* size of stack for pushes and pops *)
- AREALENGTH = TYLPATHLEN; (* see also "sysdependent" proc for this value*)
-
- CR = 13; (* numbers of certain ascii characters *)
- LF = 10;
- HT = 9;
- FF = 12;
- ERRSIGNAL = '?';
- ERRNOTBAD = 0;
- ERRBAD = 1;
- ERRREALBAD = 2;
-
-
- READACCESS = 4;
- WRITEACCESS = 2;
- NOPATH = 0;
- FONTPATH = 3;
-
-
-
- (*===========================TYPES=============================*)
- type
- (* ---- Bytes ---- *)
-
- Inbyt = -128 .. 127;
-
- OctByt = 0 .. 256; (* DVI commands are 0..255, but we need
- one more for an internal flag *)
- bytefile = packed file of Inbyt;
-
- (* ---- Strings ---- *)
- asciicode = 32 .. 126;
- charstring = packed array [1 .. ARRLIMIT] of char;
- ascstring = packed array [1 .. ARRLIMIT] of asciicode;
- (* rep for character strings *)
- strng = record
- len: 0 .. ARRLIMIT;
- str:charstring;
- end;
- (* rep for ascii strings *)
- astrng = record
- len: 0 .. ARRLIMIT;
- str: ascstring;
- end;
- (* byte strings *)
- pOstring = ^Ostring;
- Ostring = packed array[1 .. MAXOLEN] of OctByt;
-
- (* ---- PUBLIC types ---- *)
- VThickness = LoVThick .. HiVThick;
- VectKind = (VKCirc, VKVert, VKHort);
- BeamKind = (regular, grace);
- SplineKind = (BSPL, INTBSPL, CATROM, CARD);
- LineStyle = (solid, dotted, dashed, dotdash);
- ScaledPts = integer;
- MusIndex = integer;
- VecIndex = integer;
-
- ThickAryType = array[0 .. MAXSPLINESEGS] of VThickness;
- SplineSegments = array[1 .. MAXSPLINESEGS, 1 .. 2] of ScaledPts;
- ControlPoints = array [0 .. MAXCTLPTSp3, 1 .. 2] of ScaledPts;
-
-
- (* ----- Private Types ---- *)
- FontInfRec = record
- Cht, Cdp, Cwd : ScaledPts;
- Angle : real;
- end;
-
- pVectFontInfRec = ^VectFontInfRec; (* vector font info *)
- VectFontInfRec = record
- vkind : VectKind;
- DesSize : ScaledPts;
- PenSize : ScaledPts;
- psize : VThickness;
- MaxVectLen : ScaledPts;
- FontName : strng;
- Cksum : integer;
- Isdefined : boolean;
- DVIFontNum: integer;
- FontInfo : array [0 .. 127] of FontInfRec;
- end;
-
- pMusFontInfRec = ^MusFontInfRec; (* music font info *)
- MusFontInfRec = record
- DesSize : ScaledPts;
- Family : integer;
- FontName : strng;
- Cksum : integer;
- Isdefined : boolean;
- DVIFontNum: integer;
- Staffsize : integer;
- ghu : ScaledPts;
- gvu : ScaledPts;
- FontInfo : array [0 .. 127] of FontInfRec;
- end;
-
- pLabFontInfRec = ^LabFontInfRec; (* label fonts info *)
- LabFontInfRec = record
- DesSize : ScaledPts;
- FontName : strng;
- Cksum : integer;
- Isdefined : boolean;
- DVIFontNum : integer;
- internalnumber : integer;
- spacewidth : ScaledPts;
- end;
-
-
- (* list of dvi-strings *)
- dvistary = array[1 .. MAXDVISTRINGS] of pOstring;
-
- DVIBuftype = record
- TotByteLen : integer;
- Numstrings : integer;
- curstrindex : integer;
- Dstrings : dvistary;
- end;
-
- (* representation of list of fonts that have to be defined
- * before we output the BOP of the page we
- * just scanned
- *)
- ToBeDefinedRec = record
- which : char;
- indx : integer;
- end;
-
- stackrec = record
- sh, sv, sw, sx, sy, sz: integer;
- end;
-
- Stacktype = array [0 .. STACKSIZE] of stackrec;
-
- Oneby4Vector = array[1 .. 4] of real;
- Fourby4Matrix = array[1 .. 4, 1 .. 4] of real;
- Oneby5Vector = array[1 .. 5] of real;
-
- Primitive = Aline .. Afigure;
-
- pItem = ^Item;
- figptr = ^Figure;
-
- Item = packed record
- nextitem : pItem;
- BBlx, BBby, BBrx, BBty : ScaledPts; (* Bounding box *)
- itemthick : VThickness;
- itemvec : VectKind;
- itempatt : LineStyle;
- case kind : Primitive of
- Aline : ( lx1, ly1, lx2, ly2 : ScaledPts;
- );
- Aspline : ( spltype : SplineKind;
- sclosed : boolean;
- dosmarks : integer;
- nsplknots : integer;
- spts : ControlPoints;
- );
- Attspline : ( tspltype : SplineKind;
- tclosed : boolean;
- dottmarks : integer;
- nttknots : integer;
- ttpts : ControlPoints;
- ttarry : ThickAryType;
- );
- Abeam : ( bx1, by1, bx2, by2 : ScaledPts;
- staf : integer;
- bkind : BeamKind;
- );
- Atieslur : ( ntknots : integer;
- minth, maxth : VThickness;
- tspts : ControlPoints;
- );
- Aarc : ( acentx, acenty : ScaledPts;
- aradius : ScaledPts;
- firstang, lastang : integer;
- narcknots : integer;
- arcpts : ControlPoints;
- );
- Alabel : ( labx, laby : ScaledPts;
- fontstyle : integer;
- labeltext : strng;
- );
- Afigure : ( figtheta : real;
- fsx, fsy : real;
- fdx, fdy : ScaledPts;
- preWid, preHt : ScaledPts;
- postWid, postHt : ScaledPts;
- depthnumber : integer;
- body : figptr;
- );
- end;
-
-
- Figure = record
- things : pItem;
- end;
-
-
- (*==============================VARS============================*)
- var
- (* ----- Private vars *)
- catrommtx : Fourby4Matrix; (* basis matrix for catmul-rom splines*)
- bsplmtx : Fourby4Matrix; (* basis matrix for B-splines *)
- cardmtx : Fourby4Matrix; (* Cardinal spline matrix *)
- lastPoint : integer; (* num of output points *)
- intervals : integer; (* count of spline interval we are on *)
- ourxpos, (* internal x-position on page *)
- ourypos, (* internal y-position on page *)
- ourfontnum : integer; (* internal number of TeX font currently in use*)
- ourpushdepth : integer; (* depth of internal pushes *)
- origTexfont : integer; (* number of TeX font in use before tyling *)
-
- GDVIBuf : DVIBuftype; (* Global DVI buffer that contains a list of
- * dvi commands for this page. All dvi-cmds
- * parsed are put here and possibly modified
- * before being written to the output file
- *)
-
- VFontTable : array [1 .. SizVFontTable] of pVectFontInfRec;
- MFontTable : array [1 .. SizMFontTable] of pMusFontInfRec;
- LFontTable : array [1 .. SizLFontTable] of pLabFontInfRec;
- (* the font tables, and the number of fonts defined in each *)
- VFontsDefd,
- MFontsDefd,
- LFontsDefd : integer;
-
- GDVIFN : integer; (* dvi font number currently in use *)
-
- (* table of fonts yet To-Be-Defined *)
- TBD : array[1 .. MAXTBDs] of ToBeDefinedRec;
- FTBDs : integer; (* number of fonts to be defined for current page *)
-
- pageitems : pItem; (* list of primitives in current use in the current
- * figure on the current page
- *)
-
- TotBytesWritten : integer;
- ourq : integer; (* the 'q' for the postpost *)
- specstart: integer; (* the place in the DVI buffer where the
- * start of the special begins.
- * this is so that we know how far to back up
- * and over-write the old \special macro string
- * with the cmds of our 'macro-expansion'
- *)
-
- multifigure : integer; (* depth of definition recursion of figures *)
- didnewfonts : boolean; (* did we define the new fonts for this page? *)
- prevfont : integer; (* to keep track of prev font before the
- * PUSH and expansion of the special
- *)
-
- pgfigurenum : integer; (* figure number for this page *)
- currpagenum : integer; (* number of page we are on *)
- skiptsclamp : boolean; (* DEBUG: should we skip post-clamping ties *)
- dviBBlx, dviBBrx, (* Bounding box of figure in DVI space *)
- dviBBby, dviBBty : ScaledPts;
- ErrorOccurred : boolean; (* global flag in case some error happened *)
-
-
- thefilename, realnameoffile : charstring; (* used externally *)
-
- (* ----- End private vars *)
-
-
- tfmbyte : Inbyt;
-
- vaxbyt : Inbyt;
-
- tfm: array[-100 .. TFMSIZE] of OctByt;
-
- xord: array [char] of asciicode;
- xchr: array [0 .. 255] of char;
- outname: strng; (* name of output file *)
- tfmname : strng; (* name of a .tfm file *)
- dvifname : strng; (* name of the input dvi file *)
- logfilnam: strng; (* name of the log file *)
-
- dvifile: bytefile;
- tfmfile: bytefile;
- outputfil: bytefile;
- logfile : text;
-
- curfont: integer;
- s : 0 .. STACKSIZE;
- h, v, w, x, y, z: integer;
- stack: Stacktype;
-
- font: array [0 .. MAXFONTS] of
- record
- num: integer;
- name: astrng;
- checksum: integer;
- scaledsize: integer;
- designsize: integer;
- space: integer;
- bc: integer;
- ec: integer;
- widths: array [0 .. 127] of ScaledPts
- end;
- nf : 0 .. MAXFONTS;
-
- MINREAL : real; (* a system-dependent 'constant' *)
- b0, b1, b2, b3: OctByt;
- inwidth: array [0 .. 255] of integer;
- tfmchecksum: integer;
- conv: real;
- trueconv: real;
- numerator,
- denominator: integer;
- defaultdirectory: strng;
- mag,
- magfactor: real;
- maxv, maxh, maxs : integer;
- maxpages,
- totalpages : integer;
- resolution: real;
- inpostamble : boolean;
- newbackptr,
- oldbackptr : integer;
- p, k : integer;
- waste : integer;
-
-
- (* ==================forward declarations============================ *)
-
- { These hooks assume that the parameters are filled "correctly",
- and are already transformed into 4th Quadrant DVI-space }
-
-
- procedure TylTieSlur (var KnotArray: ControlPoints;
- numknots: integer;
- minthick, maxthick: VThickness); forward;
-
- procedure TylThickThinSpline (thetype : SplineKind;
- isclosed : boolean;
- var KnotArray: ControlPoints;
- var ThikThinAry: ThickAryType;
- numknots: integer;
- vec: VectKind;
- patt: LineStyle;
- domarks : integer); forward;
-
- procedure TylSpline (thetype : SplineKind;
- isclosed : boolean;
- var KnotArray: ControlPoints;
- numknots: integer;
- thick: VThickness;
- vec: VectKind;
- patt: LineStyle;
- domarks : integer); forward;
-
- procedure TylLine (xl, yb, xr, yt: ScaledPts;
- thickness: VThickness;
- vec: VectKind;
- patt: LineStyle); forward;
-
- procedure TylBeam (fromx, fromy, tox, toy: ScaledPts;
- staffsize : integer;
- kind : BeamKind); forward;
-
- procedure TylArc (radius : ScaledPts;
- centx, centy : ScaledPts;
- firstangle, secondangle : integer;
- thick : VThickness;
- vec : VectKind;
- patt: LineStyle); forward;
-
- procedure TylLabel (xpos, ypos : ScaledPts;
- fontstyle : integer;
- phrase : charstring;
- phraselen : integer); forward;
-
- (* private procedures *)
- procedure definebeams (var M : pMusFontInfRec); forward;
- procedure definevectors (var Vec: pVectFontInfRec); forward;
- procedure defineNewfonts; forward;
- procedure doTylArc (iscircle : boolean; var apts : ControlPoints;
- numknots : integer; thick : VThickness;
- vec : VectKind; patt : LineStyle); forward;
- procedure strcopy (src : charstring; var dest : charstring;
- len : integer); forward;
- procedure writestrng (s :strng; tologfile : boolean); forward;
- (* end private procs *)
-
- {------------------------------------------------------}
- procedure jumpout;
- begin
- goto 666; (* global label *)
- end;
-
-
- (*-------------- System Dependent stuff ----------------------*)
- (* the default-directory should be where the .tfm files are
- * to be found. the string len should reflect this name.
- * Check with the local site maintainer about any necessary
- * additions to the reset and rewrite procedures for opening
- * 8-bit binary files.
- *)
-
-
-
-
-
- procedure sysdependent;
- begin
-
-
- setpaths;
-
- defaultdirectory.str := TYLPATH;
- defaultdirectory.len := TYLPATHLEN; (* AREALENGTH const should be this, too *)
- writeln(TylVersion,' for Berkeley Unix');
-
- resolution := 300.0; (* just a number *)
- MINREAL := 1.0e-20; (* so that we avoid some underflows *)
- end;
-
- {------------------------------------------------------------}
- procedure complain (severity :integer);
- begin
- writeln(logfile,'Error in fig#',pgfigurenum:0,' on page ',currpagenum:0);
- case severity of
- ERRNOTBAD : begin
- write (ERRSIGNAL);
- end;
- ERRBAD : begin
- write (ERRSIGNAL);
- ErrorOccurred := true;
- end;
- ERRREALBAD : begin
- write (ERRSIGNAL,'! ');
- ErrorOccurred := true;
- end;
-
- end; (* case *)
- end;
-
- function opendvifile : boolean;
- begin
-
- strcopy (dvifname.str, thefilename, dvifname.len);
- thefilename[dvifname.len + 1] := ' ';
- if (testaccess (READACCESS, NOPATH)) then
- begin
- reset (dvifile, realnameoffile);
- opendvifile := true;
- end
- else
- begin
- writestrng(dvifname, false);
- writeln(' : DVI file not found/readable ');
- opendvifile := false;
- end;
-
- end;
-
- function opentfmfile : boolean;
- begin
-
- strcopy (tfmname.str, thefilename, tfmname.len);
- thefilename[tfmname.len + 1] := ' ';
- if (testaccess (READACCESS, FONTPATH)) then
- begin
- reset(tfmfile, realnameoffile);
- opentfmfile := true;
- end
- else
- begin
- writestrng(tfmname, false);
- writeln(' : TFM file not fount/readable ');
- opentfmfile := false;
- end;
-
- end;
-
- procedure openoutputfile;
- begin
-
- strcopy (outname.str, thefilename, outname.len);
- thefilename[outname.len + 1] := ' ';
- if (testaccess (WRITEACCESS, NOPATH)) then
- rewrite (outputfil, realnameoffile)
- else
- begin
- writestrng(outname, false);
- writeln(' : Output file not writable');
- jumpout;
- end;
-
- end;
-
- procedure openlogfile;
- begin
-
- strcopy (logfilnam.str, thefilename, logfilnam.len);
- thefilename[logfilnam.len + 1] := ' ';
- if (testaccess (WRITEACCESS, NOPATH)) then
- rewrite (logfile, realnameoffile)
- else
- begin
- writestrng(logfilnam, false);
- writeln(' : Log file not writable');
- jumpout;
- end;
-
- end;
-
-
- (* &&Module Tylsupport *)
-
-
- {---------------------------------------------------}
- procedure ClearBufString (var s : pOstring);
- (* clear a DVI buffer string to contain no-ops*)
- var i : integer;
- begin
- for i := 1 to MAXOLEN do
- s^[i] := NOP;
- end;
-
- {---------------------------------------------------}
- function NewBufString : pOstring;
- var s : pOstring;
- begin
- new (s);
- ClearBufString (s);
- NewBufString := s;
- end;
-
-
-
- (* NOTATION::
- * All procedures that put a dvi-command into the
- * temporary buffer are prefixed with "cmd"...
- * Functions that deal with reading .tfm files are prefixed
- * with "T" or have "tfm" in their names.
- * Functions that deal with reading DVI files are
- * prefixed with a "D".
- *)
-
- {--------------------------------------------}
- procedure cmd1byte (cmd : OctByt);
- begin
- with GDVIBuf do
- begin
- if (Numstrings > MAXDVISTRINGS) then (* buffer full *)
- begin
- complain (ERRREALBAD);
- writeln (logfile,'error: too many dvistrings. Totbytes = ',TotByteLen);
- jumpout;
- end;
- if (curstrindex > MAXOLEN) then (* current string full *)
- begin
- Numstrings := Numstrings + 1;
- if (Dstrings[Numstrings] <> nil) then
- dispose (Dstrings[Numstrings]);
- Dstrings[Numstrings] := NewBufString;
- ClearBufString(Dstrings[Numstrings]);
- curstrindex := 1;
- end;
- Dstrings[Numstrings]^[curstrindex] := cmd; (* insert command byte *)
- TotByteLen := TotByteLen + 1;
- curstrindex := curstrindex + 1;
- end;
- end;
-
-
- {---------------------------------------------------}
- procedure cmd2byte (cmd : integer);
- begin
- cmd1byte (cmd div 256);
- cmd1byte (cmd mod 256);
- end;
-
- {---------------------------------------------------}
- procedure cmd3byte (cmd : integer);
- begin
- cmd1byte (cmd div TWO16);
- cmd1byte ((cmd div 256) mod 256);
- cmd1byte (cmd mod 256);
- end;
-
- {---------------------------------------------------}
- procedure cmd4byte (cmd : integer);
- var tmp : integer;
- begin
- tmp := cmd;
- if (tmp >= 0) then
- begin
- cmd1byte (tmp div TWO24);
- end
- else
- begin
- tmp := tmp + TWO31 + 1; (* need the +1 *)
- cmd1byte (tmp div TWO24 + 128);
- end;
- tmp := tmp mod TWO24;
- cmd1byte (tmp div TWO16);
- tmp := tmp mod TWO16;
- cmd1byte (tmp div 256);
- cmd1byte (tmp mod 256);
- end;
-
- {---------------------------------------------------}
- (* ### may be system dependent as integers are assumed
- to be signed 32-bits *)
-
- procedure cmdSigned (i : integer; numbytes: integer);
- var tmp : integer;
- begin
- if (numbytes = 4) then
- cmd4byte (i)
- else
- begin (* <= 3 bytes *)
- tmp := i;
- if (numbytes = 3) then
- begin
- if (tmp < 0) then
- tmp := tmp + TWO24;
- cmd1byte (tmp div TWO16);
- tmp := tmp mod TWO16;
- cmd1byte (tmp div 256);
- end;
- if (numbytes = 2) then
- begin
- if (tmp < 0) then
- tmp := tmp + TWO16;
- cmd1byte (tmp div 256);
- end;
- if (numbytes = 1) then
- begin
- if (tmp < 0) then
- tmp := tmp + 256;
- end;
- cmd1byte (tmp mod 256); (* for all *)
- end;
- end;
-
-
-
- {---------------------------------------------------}
- function Tgetvaxbyte : OctByt;
- label 9999;
- begin
- tfmbyte := tfmfile^;
- if (tfmbyte < 0) then
- Tgetvaxbyte := tfmbyte + 256
- else
- Tgetvaxbyte := tfmbyte;
- if (eof (tfmfile)) then
- begin
- complain (ERRREALBAD);
- writeln (logfile,' early EOF of tfm file! ');
- goto 9999;
- end;
- get (tfmfile);
- 9999:
- end;
-
-
- {---------------------------------------------------}
- procedure readtfmword;
-
- begin
-
- b0 := Tgetvaxbyte;
- b1 := Tgetvaxbyte;
- b2 := Tgetvaxbyte;
- b3 := Tgetvaxbyte;
-
- end;
-
-
- {---------------------------------------------------}
- function DVaxByte : OctByt;
- label 99;
- begin
- vaxbyt := dvifile^;
- if (eof (dvifile)) then
- begin
- DVaxByte := 0;
- goto 99;
- end;
- if (vaxbyt < 0) then
- DVaxByte := vaxbyt + 256
- else
- DVaxByte := vaxbyt;
- get (dvifile);
- 99:
- end;
-
-
-
- {---------------------------------------------------}
- (* get a byte from the DVI file, but do not copy it into the DVIbuffer *)
- function Dgrabbyte : integer;
- var
- b: OctByt;
- begin
- if eof(dvifile) then
- Dgrabbyte := 0
- else
- begin
-
- b := DVaxByte;
-
- Dgrabbyte := b;
- end;
- end;
-
-
- {---------------------------------------------------}
- function Dget1byte : integer;
- var
- b: OctByt;
- begin
- if eof(dvifile) then
- Dget1byte := 0
- else
- begin
-
- b := DVaxByte;
-
- Dget1byte := b
- end;
- cmd1byte(b);
- end;
-
- {---------------------------------------------------}
- function Dsign1byte : integer;
- var
- b: OctByt;
- begin
-
- b := DVaxByte;
-
- if b < 128 then
- Dsign1byte := b
- else
- Dsign1byte := b - 256;
- cmd1byte(b);
- end;
-
- {---------------------------------------------------}
- function Dget2byte : integer;
- var
- a, b: OctByt;
- begin
-
- a := DVaxByte;
- b := DVaxByte;
-
- Dget2byte := a * 256 + b;
- cmd1byte(a);
- cmd1byte(b);
- end;
-
- {---------------------------------------------------}
- function Dsign2byte : integer;
- var
- a, b: OctByt;
- begin
-
- a := DVaxByte;
- b := DVaxByte;
-
- if a < 128 then
- Dsign2byte := a * 256 + b
- else
- Dsign2byte := (a - 256) * 256 + b;
- cmd1byte(a);
- cmd1byte(b);
- end;
-
- {---------------------------------------------------}
- function Dget3byte : integer;
- var
- a, b, c: OctByt;
- begin
-
- a := DVaxByte;
- b := DVaxByte;
- c := DVaxByte;
-
- Dget3byte := (a * 256 + b) * 256 + c;
- cmd1byte(a);
- cmd1byte(b);
- cmd1byte(c);
- end;
-
- {---------------------------------------------------}
- function Dsign3byte : integer;
- var
- a, b, c: OctByt;
- begin
-
- a := DVaxByte;
- b := DVaxByte;
- c := DVaxByte;
-
- if a < 128 then
- Dsign3byte := (a * 256 + b) * 256 + c
- else
- Dsign3byte := ((a - 256) * 256 + b) * 256 + c;
- cmd1byte(a);
- cmd1byte(b);
- cmd1byte(c);
- end;
-
- {---------------------------------------------------}
- function Dsign4byte : integer;
- var
- a, b, c, d: OctByt;
- begin
-
- a := DVaxByte;
- b := DVaxByte;
- c := DVaxByte;
- d := DVaxByte;
-
- if a < 128 then
- Dsign4byte := ((a * 256 + b) * 256 + c) * 256 + d
- else
- Dsign4byte := (((a - 256) * 256 + b) * 256 + c) * 256 + d;
- cmd1byte(a);
- cmd1byte(b);
- cmd1byte(c);
- cmd1byte(d);
- end;
-
-
- {---------------------------------------------------}
- (* write a byte out to the ouput file, but if we
- * encounter the font flag, define the new fonts, and
- * continue
- *)
- procedure OutputByte (b : OctByt);
- var x : Inbyt;
- n : integer;
- begin
- n := b;
- if (n = OURFONTFLAG) then
- begin (* our special macro-flag *)
- n := NOP; (* nullify it *)
- if (not didnewfonts) then
- begin
- didnewfonts := true;
- defineNewfonts; (* expand the defns in the outfile itself *)
- end;
- end; (* if *)
-
- if (n > 127) then
- begin
- x := n - 256;
- end
- else
- x := n;
- outputfil^ := x;
- put (outputfil);
-
- TotBytesWritten := TotBytesWritten + 1; (* keep count of all bytes *)
- end;
-
- {---------------------------------------------------}
- procedure Output2Byte (i : integer);
- begin
- OutputByte (i div 256);
- OutputByte (i mod 256);
- end;
- E_O_F
- else
- echo "will not over write ./src/textyl.pas.aa"
- fi
- chmod 644 ./src/textyl.pas.aa
- if [ `wc -c ./src/textyl.pas.aa | awk '{printf $1}'` -ne 26016 ]
- then
- echo `wc -c ./src/textyl.pas.aa | awk '{print "Got " $1 ", Expected " 26016}'`
- fi
- if `test ! -s ./src/tylext.c`
- then
- echo "writing ./src/tylext.c"
- cat > ./src/tylext.c << 'E_O_F'
- /* External procedures for dvitype */
- /* Written by: H. Trickey, 2/19/83 (adapted from TeX's ext.c) */
-
- #include "texpaths.h" /* defines default TEXFONTS path */
- #include "h00vars.h" /* defines Pascal I/O structure */
-
- char *fontpath;
-
- char *getenv();
-
- /*
- * setpaths is called to set up the pointer fontpath
- * as follows: if the user's environment has a value for TEXFONTS
- * then use it; otherwise, use defaultfontpath.
- */
- setpaths()
- {
- register char *envpath;
-
- if ((envpath = getenv("TEXFONTS")) != NULL)
- fontpath = envpath;
- else
- fontpath = defaultfontpath;
- }
-
- #define namelength 100 /* should agree with defn in textyl program*/
- extern char thefilename[],realnameoffile[]; /* these have size namelength */
-
- /*
- * testaccess(amode,filepath)
- *
- * Test whether or not the file whose name is in the global thefilename
- * can be opened for reading (if mode=READACCESS)
- * or writing (if mode=WRITEACCESS).
- *
- * The filepath argument is one of the ...FILEPATH constants defined below.
- * If the filename given in thefilename does not begin with '/', we try
- * prepending all the ':'-separated areanames in the appropriate path to the
- * filename until access can be made, if it ever can.
- *
- * The realnameoffile global array will contain the name that yielded an
- * access success.
- */
-
- #define READACCESS 4
- #define WRITEACCESS 2
-
- #define NOFILEPATH 0
- #define FONTFILEPATH 3
-
- bool
- testaccess(amode,filepath)
- int amode,filepath;
- {
- register bool ok;
- register char *p;
- char *curpathplace;
- int f;
-
- switch (filepath) {
- case NOFILEPATH:
- curpathplace = NULL;
- break;
- case FONTFILEPATH:
- curpathplace = fontpath;
- break;
- }
- if (thefilename[0] == '/') /* file name has absolute path */
- curpathplace = NULL;
- do {
- packrealnameoffile (&curpathplace);
- if (amode == READACCESS)/* use system call "access" to see if we
- could read it */
- if (access (realnameoffile, READACCESS) == 0)
- ok = TRUE;
- else
- ok = FALSE;
- else {
- /* WRITEACCESS: use creat to see if we could create it, but close
- the file again if we''re OK, to let pc open it for real */
- f = creat (realnameoffile, 0666);
- if (f >= 0)
- ok = TRUE;
- else
- ok = FALSE;
- if (ok)
- close (f);
- }
- } while (!ok && curpathplace != NULL);
- if (ok) { /* pad realnameoffile with blanks, as
- Pascal wants */
- for (p = realnameoffile; *p != '\0'; p++)
- /* nothing: find end of string */
- ;
- while (p < &(realnameoffile[namelength]))
- *p++ = ' ';
- }
- return (ok);
- }
-
- /*
- * packrealnameoffile(cpp) makes realnameoffile contain the directory at *cpp,
- * followed by '/', followed by the characters in thefilename up until the
- * first blank there, and finally a '\0'. The cpp pointer is left pointing
- * at the next directory in the path.
- * But: if *cpp == NULL, then we are supposed to use thefilename as is.
- */
- packrealnameoffile(cpp)
- char **cpp;
- {
- register char *p,
- *realname;
-
- realname = realnameoffile;
- if ((p = *cpp) != NULL) {
- while ((*p != ':') && (*p != '\0')) {
- *realname++ = *p++;
- if (realname == &(realnameoffile[namelength - 1]))
- break;
- }
- if (*p == '\0')
- *cpp = NULL; /* at end of path now */
- else
- *cpp = p + 1; /* else get past ':' */
- *realname++ = '/'; /* separate the area from the name to
- follow */
- }
- /* now append thefilename to realname... */
- p = thefilename;
- while (*p != ' ') {
- if (realname >= &(realnameoffile[namelength - 1])) {
- fprintf (stderr, "! Full file name is too long\n");
- break;
- }
- *realname++ = *p++;
- }
- *realname = '\0';
- }
- E_O_F
- else
- echo "will not over write ./src/tylext.c"
- fi
- chmod 644 ./src/tylext.c
- if [ `wc -c ./src/tylext.c | awk '{printf $1}'` -ne 3668 ]
- then
- echo `wc -c ./src/tylext.c | awk '{print "Got " $1 ", Expected " 3668}'`
- fi
- if `test ! -s ./src/textyl.pas.ad`
- then
- echo "writing ./src/textyl.pas.ad"
- cat > ./src/textyl.pas.ad << 'E_O_F'
- * given unit-radius. Scale those points to fit the desired radius
- *)
- procedure defineCircleCpts (rad : ScaledPts; centx, centy : ScaledPts;
- var CircleCpt : ControlPoints;
- var numpts : integer);
- const UnitRadius = 16777216; (* TWO24 scaledpts *)
- var ratio : real;
- begin
- if (rad = 0) then
- begin
- complain (ERRBAD);
- writeln(logfile,'Error in fig#',pgfigurenum:0,' on page ',currpagenum:0);
- writeln(logfile,'Zero length radius for circle! Setting to 1 sp');
- rad := 1;
- end;
- ratio := float(rad) / float(UnitRadius);
- numpts := 16;
- CircleCpt[1,1] := round (ratio * 16777216.00000) + centx;
- CircleCpt[1,2] := 0 + centy; {round (ratio * 0.00000)}
- CircleCpt[2,1] := round (ratio * 15500126.47492) + centx;
- CircleCpt[2,2] := round (ratio * 6420362.60441) + centy;
- CircleCpt[3,1] := round (ratio * 11863283.20303) + centx;
- CircleCpt[3,2] := round (ratio * 11863283.20303) + centy;
- CircleCpt[4,1] := round (ratio * 6420362.60441) + centx;
- CircleCpt[4,2] := round (ratio * 15500126.47492) + centy;
- CircleCpt[5,1] := 0 + centx; {round (ratio * -0.00000) }
- CircleCpt[5,2] := round (ratio * 16777216.00000) + centy;
- CircleCpt[6,1] := round (ratio * -6420362.60441) + centx;
- CircleCpt[6,2] := round (ratio * 15500126.47492) + centy;
- CircleCpt[7,1] := round (ratio * -11863283.20303) + centx;
- CircleCpt[7,2] := round (ratio * 11863283.20303) + centy;
- CircleCpt[8,1] := round (ratio * -15500126.47492) + centx;
- CircleCpt[8,2] := round (ratio * 6420362.60441) + centy;
- CircleCpt[9,1] := round (ratio * -16777216.00000) + centx;
- CircleCpt[9,2] := 0 + centy; {round (ratio * -0.00000)}
- CircleCpt[10,1] := round (ratio * -15500126.47492) + centx;
- CircleCpt[10,2] := round (ratio * -6420362.60441) + centy;
- CircleCpt[11,1] := round (ratio * -11863283.20303) + centx;
- CircleCpt[11,2] := round (ratio * -11863283.20303) + centy;
- CircleCpt[12,1] := round (ratio * -6420362.60441) + centx;
- CircleCpt[12,2] := round (ratio * -15500126.47492) + centy;
- CircleCpt[13,1] := 0 + centx; {round (ratio * 0.00000) }
- CircleCpt[13,2] := round (ratio * -16777216.00000) + centy;
- CircleCpt[14,1] := round (ratio * 6420362.60441) + centx;
- CircleCpt[14,2] := round (ratio * -15500126.47492) + centy;
- CircleCpt[15,1] := round (ratio * 11863283.20303) + centx;
- CircleCpt[15,2] := round (ratio * -11863283.20303) + centy;
- CircleCpt[16,1] := round (ratio * 15500126.47492) + centx;
- CircleCpt[16,2] := round (ratio * -6420362.60441) + centy;
- (* create the pre-list phantom *)
- CircleCpt[0,1] := CircleCpt[16,1];
- CircleCpt[0,2] := CircleCpt[16,2];
- end;
-
-
- {---------------------------------------------------------------}
- (* compute control points for an arc going from startangle to
- * stopangle, centered at (centx, centy)
- *)
- procedure definearcpts (rad : ScaledPts; centx, centy : ScaledPts;
- startang, stopang : integer;
- var cpts : ControlPoints;
- var nknots : integer);
- var n : integer;
- a, b, curr, delta: real;
- i : integer;
- begin
- a := startang * DEGTORAD;
- b := stopang * DEGTORAD;
- n := 16;
-
- if (a > b) then
- begin
- a := a - (2 * PI);
- end;
-
- delta := abs(b - a) / n;
-
- if (a = b) then
- begin
- complain (ERRNOTBAD);
- writeln(logfile,'Error in compute arc points:: should be a circle');
- end;
- curr := a;
- i := 1;
- while ((curr <= b)) do
- begin (* make arc about (centx,centy) *)
- cpts[i,1] := round (rad * cos (curr)) + centx;
- cpts[i,2] := round (rad * sin (curr)) + centy;
- i := i + 1;
- curr := curr + delta;
- end; (* while *)
-
- (* go one point beyond --
- * around the arc so that we can have good smoothness
- * for this phantom point
- *)
-
- cpts[i,1] := round (rad * cos (b + delta)) + centx;
- cpts[i,2] := round (rad * sin (b + delta)) + centy;
-
- (* and one phantom point before the list *)
- cpts[0,1] := round (rad * cos (a - delta)) + centx;
- cpts[0,2] := round (rad * sin (a - delta)) + centy;
-
-
- nknots := i-1;
- end;
-
-
-
- (* &&Module spline.p *)
- (*
- Procedures below may make free use of the global variables
- arrayXY [list of control points]
- pointmatrix [list of spline segments]
- knot [list of spline knots]
- catrommtx [matrix for Catmull-Rom splines]
- bsplmtx [matrix for B-splines]
- lastPoint, intervals
- *)
-
-
- {-----------------------------------------------------}
- function max (a, b: integer):integer;
- begin
- if (a > b) then
- max := a
- else
- max := b;
- end;
-
- {-----------------------------------------------------}
- function min (a, b: integer):integer;
- begin
- if (a < b) then
- min := a
- else
- min := b;
- end;
-
- {---------------------------------------------------------------------}
- (* initialize the Catmull-Rom basis matrix *)
-
- procedure initcrmatrix;
- begin
- catrommtx[1,1] := -0.5; catrommtx[1,2] := 1.5;
- catrommtx[1,3] := -1.5; catrommtx[1,4] := 0.5;
- catrommtx[2,1] := 1.0; catrommtx[2,2] := -2.5;
- catrommtx[2,3] := 2.0; catrommtx[2,4] := -0.5;
- catrommtx[3,1] := -0.5; catrommtx[3,2] := 0.0;
- catrommtx[3,3] := 0.5; catrommtx[3,4] := 0.0;
- catrommtx[4,1] := 0.0; catrommtx[4,2] := 1.0;
- catrommtx[4,3] := 0.0; catrommtx[4,4] := 0.0;
- end;
-
- {-----------------------------------------------------}
- procedure initbsplmatrix;
- begin
- bsplmtx[1,1] := -1.0/6.0; bsplmtx[1,2] := 0.5;
- bsplmtx[1,3] := -0.5; bsplmtx[1,4] := 1.0/6.0;
- bsplmtx[2,1] := 0.5; bsplmtx[2,2] := -1.0;
- bsplmtx[2,3] := 0.5; bsplmtx[2,4] := 0.0;
- bsplmtx[3,1] := -0.5; bsplmtx[3,2] := 0.0;
- bsplmtx[3,3] := 0.5; bsplmtx[3,4] := 0.0;
- bsplmtx[4,1] := 1.0/6.0; bsplmtx[4,2] := 2.0/3.0;
- bsplmtx[4,3] := 1.0/6.0; bsplmtx[4,4] := 0.0;
- end;
-
- {--------------------------------------------------------}
- (* init the Cardinal Spline Matrix *)
- procedure initcardmatrix;
- begin
- cardmtx[1,1] := -1.0; cardmtx[1,2] := 1.0;
- cardmtx[1,3] := -1.0; cardmtx[1,4] := 1.0;
- cardmtx[2,1] := 2.0; cardmtx[2,2] := -2.0;
- cardmtx[2,3] := 1.0; cardmtx[2,4] := -1.0;
- cardmtx[3,1] := -1.0; cardmtx[3,2] := 0.0;
- cardmtx[3,3] := 1.0; cardmtx[3,4] := 0.0;
- cardmtx[4,1] := 0.0; cardmtx[4,2] := 1.0;
- cardmtx[4,3] := 0.0; cardmtx[4,4] := 0.0;
- end;
-
- {--------------------------------------------------------}
- procedure initallspline;
- begin
- initcrmatrix;
- initbsplmatrix;
- initcardmatrix;
- end;
-
-
- {-----------------------------------------------------}
- procedure matXvector (var m: Fourby4Matrix; (* IN *)
- var v: Oneby4Vector; (* IN *)
- var result: Oneby4Vector); (* OUT *)
- var t: Oneby4Vector;
- begin
- t[1] := v[1]*m[1,1] + v[2]*m[1,2] + v[3]*m[1,3] + v[4]*m[1,4];
- t[2] := v[1]*m[2,1] + v[2]*m[2,2] + v[3]*m[2,3] + v[4]*m[2,4];
- t[3] := v[1]*m[3,1] + v[2]*m[3,2] + v[3]*m[3,3] + v[4]*m[3,4];
- t[4] := v[1]*m[4,1] + v[2]*m[4,2] + v[3]*m[4,3] + v[4]*m[4,4];
- result[1] := t[1]; result[2] := t[2];
- result[3] := t[3]; result[4] := t[4];
- end;
-
- {-----------------------------------------------------}
- (* actually the dot-product *)
- function vecXvec (var v1, v2: Oneby4Vector) : real;
- begin
- vecXvec := v1[1]*v2[1] + v1[2]*v2[2] + v1[3]*v2[3] + v1[4]*v2[4];
- end;
-
-
- {------------------------------------------------------}
- (* basXctl is the pre-computed BasisMatrix times the control-point vector *)
-
- function splinePosition (var basXctl : Oneby4Vector; (* IN *)
- t : real ) : real;
- var tvect : Oneby4Vector; { vector of t values for spline matrix}
- begin
- tvect[4] := 1.0;
- tvect[3] := t;
- tvect[2] := t * t;
- if (tvect[2] <= MINREAL) then
- begin (* avoid underflow problems *)
- tvect[2] := 0.0;
- end;
- tvect[1] := t * tvect[2]; (* t^3 *)
- splinePosition := vecXvec (tvect, basXctl);
- end;
-
- {-------------------------------------------------}
- function TwoToThe (n : integer) : integer;
- label 78;
- var i : integer;
- tmp : integer;
- begin
- tmp := 1;
- if (n <= 0) then
- goto 78;
- if (n < 6) then
- begin
- case n of
- 1 : tmp := 2;
- 2 : tmp := 4;
- 3 : tmp := 8;
- 4 : tmp := 16;
- 5 : tmp := 32;
- end; (* case *)
- end (* if *)
- else
- begin
- tmp := 32;
- for i := 6 to n do
- tmp := tmp * 2;
- end;
- 78:
- TwoToThe := tmp;
- end;
-
- {------------------------------------------------------}
- function distance (x0, y0, x1, y1 : real) : real;
- var res : real;
- begin
- res := sqrt ( (x1 - x0)*(x1 - x0) + (y1 - y0)*(y1 - y0));
- distance := res;
- end;
-
-
- {------------------------------------------------------}
- (* compute the number of subdivisions for this span.
- We do this by a quadrature method and a simple linear-distance
- metric. This is not optimal in the number of subdivisions actually
- required, but is computationally efficient and accurate to the
- nearest power of 2 .
- *)
- function numsubdivisions (var XtimesBas, YtimesBas : Oneby4Vector;
- resolution : ScaledPts): integer;
- var n : integer;
- d : integer;
- t : real;
- x0, y0, xt, yt : real;
- begin
- x0 := splinePosition (XtimesBas, 0.0);
- y0 := splinePosition (YtimesBas, 0.0);
-
- t := 1.0;
- n := 0;
- xt := splinePosition (XtimesBas, t);
- yt := splinePosition (YtimesBas, t);
-
- while ((round (distance (x0, y0, xt, yt)) > resolution) or
- (n < 1)) do
- begin
- t := t / 2.0; (* perform the quadrature *)
- n := n + 1;
- xt := splinePosition (XtimesBas, t);
- yt := splinePosition (YtimesBas, t);
- end; (* while *)
- numsubdivisions := TwoToThe (n);
- end;
-
- {------------------------------------------------------------------------}
- (* compute new control vertices such that the resulting spline
- * will interpolate through the old control points.
- * This will work as long as the actual arc length
- * between consecutive nodes does not vary from span to span.
- * The method is noted in Wu and Abel's CACM 20(10) Oct 77 paper
- * but the actual working method is from
- * Barsky and Greenberg's paper in
- * CG&IP 14(3) Nov 1980 pp.203-226
- *)
- procedure invertsplvertices (numpts : integer;
- isclosed : boolean;
- var xys : ControlPoints); (* INOUT *)
- var i : integer;
- beta, Xrprime, Yrprime : array[0..MAXCTLPTS] of real;
- tempxys : ControlPoints;
- begin
- (* compute the values of beta *)
- beta[1] := 0.25;
- for i := 2 to numpts + 1 do
- beta[i] := 1.0 / (4.0 - beta[i - 1]);
-
- (* and the r primes from the original vertices *)
- Xrprime[1] := beta[1] * xys[1,1] * 5.0;
- Yrprime[1] := beta[1] * xys[1,2] * 5.0;
- for i := 2 to numpts -1 do
- begin
- Xrprime[i] := beta[i] * (6.0 * xys[i,1] - Xrprime[i - 1]);
- Yrprime[i] := beta[i] * (6.0 * xys[i,2] - Yrprime[i - 1]);
- end; (* for *)
- Xrprime[numpts] := beta[numpts] * (5.0 * xys[numpts,1] - Xrprime[numpts - 1]);
- Yrprime[numpts] := beta[numpts] * (5.0 * xys[numpts,2] - Yrprime[numpts - 1]);
-
- (* Now perform the back-substitution from the bottom up *)
- tempxys[numpts,1] := round (Xrprime[numpts]);
- tempxys[numpts,2] := round (Yrprime[numpts]);
- for i := numpts - 1 downto 1 do
- begin
- tempxys[i,1] := round (Xrprime[i] - beta[i] * tempxys[i + 1, 1]);
- tempxys[i,2] := round (Yrprime[i] - beta[i] * tempxys[i + 1, 2]);
- end;
-
- if (isclosed) then
- begin
- (* at this point, we've probably been through one control-point
- * adjustment, so let's not muck it up
- *)
- tempxys[numpts+1,1] := tempxys[1,1];
- tempxys[numpts+1,2] := tempxys[1,2];
- tempxys[numpts+2,1] := tempxys[2,1];
- tempxys[numpts+2,2] := tempxys[2,2];
- tempxys[0,1] := tempxys[numpts,1];
- tempxys[0,2] := tempxys[numpts,2];
- (* copy them back *)
- for i := 0 to (numpts+2) do
- begin
- xys[i,1] := tempxys[i,1];
- xys[i,2] := tempxys[i,2];
- end;
- end (* closed *)
- else
- begin
- (* copy back *)
- for i := 2 to numpts -1 do
- begin
- xys[i,1] := tempxys[i,1];
- xys[i,2] := tempxys[i,2];
- end;
- end; (* open*)
- end;
-
-
- {-----------------------------------------------------}
- (* adjust the list of control points so that we can use
- * it for B-spline interpolation.
- * Add any "phantom" vertices necessary so that the end
- * conditions will be correct for interpolation
- *)
- procedure Bctlptadjust (isclosed : boolean; isarc : boolean;
- var n: integer; (* INOUT *)
- var xys: ControlPoints; (* INOUT *)
- var thx: ThickAryType); (* INOUT *)
- var j : integer;
- tmp : ControlPoints;
- tmpthx : ThickAryType;
- begin (* ctlpt adjust*)
-
- if (isclosed) then
- begin
- (* here, we have to supply the last 'real' point for the user,
- and add three phantoms-- one before, and two after *)
-
- if (n = 2) then
- begin
- complain (ERRBAD);
- writeln(logfile,'A closed spline requires more than 2 control points ');
- writeln(logfile,'making a temporary fix in order to continue...');
- xys[3,1] := xys[1,1];
- xys[3,2] := xys[1,2];
- end;
-
- for j := 1 to (n) do
- begin
- tmp[j, 1] := xys[j, 1];
- tmp[j, 2] := xys[j, 2];
- tmpthx[j] := thx[j];
- end;
- (* Now take care of the 'phantom' vertices *)
- tmp[n+1, 1] := xys[1, 1];
- tmp[n+1, 2] := xys[1, 2];
- tmpthx[n+1] := thx[1];
- tmp[n+2, 1] := xys[2, 1];
- tmp[n+2, 2] := xys[2, 2];
- tmpthx[n+2] := thx[2];
- tmp[n+3, 1] := xys[3, 1];
- tmp[n+3, 2] := xys[3, 2];
- tmpthx[n+3] := thx[3];
-
- if (not isarc) then
- begin
- tmp[0,1] := xys[n, 1]; (* wrap around to the real last point *)
- tmp[0,2] := xys[n, 2];
- tmpthx[0] := thx[n];
- end
- else
- begin
- tmp[0,1] := xys[0,1];
- tmp[0,2] := xys[0,2];
- tmpthx[0] := thx[0];
- end;
-
- n := n + 1; (* we supplied the 'last' point for the user *)
-
- for j := 0 to n+2 do
- begin
- xys[j,1] := tmp[j,1];
- xys[j,2] := tmp[j,2];
- thx[j] := tmpthx[j];
- end; (* for *)
- end (* if closed *)
- else
- begin (* OPEN SPLINE *)
- if (not isarc) then
- begin
- tmp[0,1] := 2 * xys[1, 1] - xys[2,1];
- tmp[0,2] := 2 * xys[1, 2] - xys[2,2];
- end
- else
- begin
- tmp[0,1] := xys[0,1];
- tmp[0,2] := xys[0,2];
- end;
- tmpthx[0] := thx[1];
-
- for j := 1 to (n) do
- begin
- tmp[j, 1] := xys[j, 1];
- tmp[j, 2] := xys[j, 2];
- tmpthx[j] := thx[j];
- end;
-
- tmp[n+1, 1] := 2 * xys[n, 1] - xys[n-1,1];
- tmp[n+1, 2] := 2 * xys[n, 2] - xys[n-1,2];
- tmpthx[n+1] := thx[n];
-
- tmp[n+2, 1] := tmp[n+1, 1];
- tmp[n+2, 2] := tmp[n+1, 2];
- tmpthx[n+2] := thx[n];
-
- for j := 0 to n+2 do
- begin
- xys[j,1] := tmp[j,1];
- xys[j,2] := tmp[j,2];
- thx[j] := tmpthx[j];
- end; (* for *)
- end; (* if open *)
-
- end;
-
-
-
- {-----------------------------------------------------}
- (* adjust the list of control points so that we can use
- * it for simple Catmull-Rom spline interpolation.
- * Add any "phantom" vertices necessary so that the end
- * conditions will be correct for interpolation
- *)
- procedure CRctlptadjust (isclosed : boolean; isarc : boolean;
- var n: integer; (* INOUT *)
- var xys: ControlPoints; (* INOUT *)
- var thx: ThickAryType); (* INOUT *)
- var j : integer;
- tmp : ControlPoints;
- tmpthx : ThickAryType;
- begin (* ctlpt adjust*)
- if (isclosed) then
- begin
- (* here, we have to supply the last 'real' point for the user,
- and add three phantoms-- one before, and two after *)
-
- if (n = 2) then
- begin
- complain (ERRBAD);
- writeln(logfile,'A closed spline requires more than 2 control points ');
- writeln(logfile,'making a temporary fix in order to continue...');
- xys[3,1] := xys[1,1];
- xys[3,2] := xys[1,2];
- end;
-
-
- for j := 1 to (n) do
- begin
- tmp[j, 1] := xys[j, 1];
- tmp[j, 2] := xys[j, 2];
- tmpthx[j] := thx[j];
- end;
- (* the phantom vertices *)
- tmp[n+1, 1] := xys[1, 1];
- tmp[n+1, 2] := xys[1, 2];
- tmpthx[n+1] := thx[1];
- tmp[n+2, 1] := xys[2, 1];
- tmp[n+2, 2] := xys[2, 2];
- tmpthx[n+2] := thx[2];
- tmp[n+3, 1] := xys[3, 1];
- tmp[n+3, 2] := xys[3, 2];
- tmpthx[n+3] := thx[3];
-
- if (not isarc) then
- begin
- tmp[0,1] := xys[n, 1]; (* wrap around to the real last point *)
- tmp[0,2] := xys[n, 2];
- tmpthx[0] := thx[n];
- end
- else
- begin
- tmp[0,1] := xys[0,1];
- tmp[0,2] := xys[0,2];
- tmpthx[0] := thx[0];
- end;
- n := n + 1; (* we supplied the 'last' point for the user *)
-
- for j := 0 to n+2 do
- begin
- xys[j,1] := tmp[j,1];
- xys[j,2] := tmp[j,2];
- thx[j] := tmpthx[j];
- end; (* for *)
- end (* if closed *)
- else
- begin (* OPEN SPLINE *)
- if (not isarc) then
- begin
- tmp[0,1] := xys[1, 1]; (* double the first point *)
- tmp[0,2] := xys[1, 2];
- end
- else
- begin
- tmp[0,1] := xys[0,1];
- tmp[0,2] := xys[0,2];
- end;
- tmpthx[0] := thx[1];
-
- for j := 1 to (n) do
- begin
- tmp[j, 1] := xys[j, 1];
- tmp[j, 2] := xys[j, 2];
- tmpthx[j] := thx[j];
- end;
-
- tmp[n+1, 1] := xys[n, 1]; (* and triple the last *)
- tmp[n+1, 2] := xys[n, 2];
- tmpthx[n+1] := thx[n];
- tmp[n+2, 1] := xys[n, 1];
- tmp[n+2, 2] := xys[n, 2];
- tmpthx[n+2] := thx[n];
-
- for j := 0 to n+2 do
- begin
- xys[j,1] := tmp[j,1];
- xys[j,2] := tmp[j,2];
- thx[j] := tmpthx[j];
- end; (* for *)
- end; (* if open *)
- end; (* ctlpt adjust *)
-
-
-
- {----------------------------------------------------------}
-
- procedure interpsplines (splinetype: SplineKind;
- isclosed: boolean;
- isanArc: boolean;
- linepatt : LineStyle;
- var basismatrix : Fourby4Matrix; (* IN *)
- numctls: integer;
- var arrayXY: ControlPoints; (* IN *)
- var pointmatrix: SplineSegments; (* OUT *)
- varythicks: boolean;
- var thickmatrix: ThickAryType; (* IN *)
- var TTmatrix: ThickAryType); (* OUT *)
- label 32;
- var xctl, yctl, { vectors of x, y posits of control points}
- wctl : Oneby4Vector; {vector of thicknesses at each ctl pt}
- t, incr: real;
- Pi: integer; { P sub i }
- i, currpt : integer;
- theresolution : ScaledPts;
-
- begin (* interp splines*)
- if ((not isclosed) and (isanArc)) then
- numctls := numctls + 1; (* lie a little *)
-
- case (splinetype) of
-
- BSPL: Bctlptadjust (isclosed, isanArc, numctls, arrayXY, thickmatrix);
-
- CARD,
- CATROM: CRctlptadjust (isclosed, isanArc, numctls, arrayXY, thickmatrix);
-
- INTBSPL: begin
- if (isclosed) then
- begin
- Bctlptadjust (true, isanArc, numctls, arrayXY, thickmatrix);
- invertsplvertices (numctls, true, arrayXY);
- end
- else
- begin
- invertsplvertices (numctls, false, arrayXY);
- Bctlptadjust (false, isanArc, numctls, arrayXY, thickmatrix);
- end; (* else *)
- end; (* Interpolating Bsplines *)
- end;
-
- if ((not isclosed) and (isanArc)) then
- numctls := numctls - 1; (* UN-lie a little *)
-
-
- (* this is the scheme:
- * val := t-vector * Basis matrix * point matrix
- * [t^3 t^2 t 1] * [[Ms]] * [Pi-1 Pi Pi+1 Pi+2]
- * where "Pi-1" is "P sub (i-1)", etc.
- *
- * But we do this in a round about way:
- * Point matrix * basis
- * then * t-vector will yield the single value
- *
- * there are certainly faster ways to do this,
- * but this is the easiest to understand
- *)
-
- currpt := 1;
- case linepatt of
- solid : theresolution := MAXVECLENsp;
- dotted,
- dashed,
- dotdash : theresolution := 3 * MAXVECLENsp; {###}
- end;
-
- for Pi := 1 to (numctls - 1) do
- begin
- xctl[1] := float(arrayXY[Pi-1, 1]);
- xctl[2] := float(arrayXY[Pi, 1]);
- xctl[3] := float(arrayXY[Pi+1, 1]);
- xctl[4] := float(arrayXY[Pi+2, 1]);
- yctl[1] := float(arrayXY[Pi-1, 2]);
- yctl[2] := float(arrayXY[Pi, 2]);
- yctl[3] := float(arrayXY[Pi+1, 2]);
- yctl[4] := float(arrayXY[Pi+2, 2]);
- matXvector (basismatrix, xctl, xctl);
- matXvector (basismatrix, yctl, yctl);
-
- (* compute the delta-t increment for this segment
- based on a metric for subdivision *)
- intervals := numsubdivisions (xctl, yctl, theresolution);
- if ((linepatt = solid) and (intervals <= 2)) then
- intervals := intervals * 2;
- incr := 1.0 / intervals;
-
- (* avoid over-flowing the "pointmatrix" *)
- if ((currpt + intervals - 1) >= MAXSPLINESEGS) then
- begin
- complain (ERRREALBAD);
- writeln (logfile,'error: Too many spline segments required.');
- writeln (logfile,' Reducing the number of control points to get output.');
- goto 32;
- end;
-
- t := 0.0;
- while (t < 0.999999999) do
- begin
- pointmatrix[currpt, 1] := round (splinePosition (xctl, t));
- pointmatrix[currpt, 2] := round (splinePosition (yctl, t));
-
- if (varythicks) then
- begin
- wctl[1] := float(thickmatrix[Pi-1]);
- wctl[2] := float(thickmatrix[Pi ]);
- wctl[3] := float(thickmatrix[Pi+1]);
- wctl[4] := float(thickmatrix[Pi+2]);
- matXvector (catrommtx, wctl, wctl); (* requires using Catmull-Rom *)
- TTmatrix[currpt] := round (splinePosition (wctl, t));
- end;
-
- t := t + incr;
- currpt := currpt + 1;
- end; (* while loop *)
-
-
- end; (* for loop *)
-
- 32:
- (* the END-condtion *)
- pointmatrix[currpt, 1] := round (splinePosition (xctl, 1.0));
- pointmatrix[currpt, 2] := round (splinePosition (yctl, 1.0));
- if (varythicks) then
- begin
- wctl[1] := thickmatrix[numctls-2];
- wctl[2] := thickmatrix[numctls-1];
- wctl[3] := thickmatrix[numctls];
- wctl[4] := thickmatrix[numctls+1];
- matXvector (catrommtx, wctl, wctl); (* requires using Catmull-Rom *)
- TTmatrix[currpt] := round (splinePosition (wctl, 1.0));
- end;
-
- lastPoint := currpt;
-
- end; (* interpsplines *)
-
-
- {----------------------------------------------------------------}
- procedure drawSpline (splinetype : SplineKind;
- isclosed: boolean;
- isanArc: boolean;
- patt : LineStyle;
- numctls: integer;
- var arrayXY: ControlPoints; (* IN *)
- var pointmatrix: SplineSegments; (* OUT *)
- varythicks: boolean;
- var thickmatrix: ThickAryType; (* IN *)
- var TTmatrix: ThickAryType); (* OUT *)
- begin
- lastPoint := 0;
-
-
- case (splinetype) of
- CATROM : interpsplines (splinetype, isclosed, isanArc, patt, catrommtx,
- numctls, arrayXY, pointmatrix,
- varythicks, thickmatrix, TTmatrix);
-
- CARD : interpsplines (splinetype, isclosed, isanArc, patt, cardmtx,
- numctls, arrayXY, pointmatrix,
- varythicks, thickmatrix, TTmatrix);
-
- BSPL : interpsplines (splinetype, isclosed, isanArc, patt, bsplmtx,
- numctls, arrayXY, pointmatrix,
- varythicks, thickmatrix, TTmatrix);
-
- INTBSPL : interpsplines (splinetype, isclosed, isanArc, patt, bsplmtx,
- numctls, arrayXY, pointmatrix,
- varythicks, thickmatrix, TTmatrix);
- end; (*Case *)
- end;
-
-
- (* &&module TeXtyl *)
- {----------------------------------------------------------------}
- (* rotate a (x,y) point about mx, my *)
- procedure ptrotate (var x, y : integer;
- mx, my: integer;
- angle : real);
- var tmpx, tmpy : integer;
- cosa, sina : real;
- begin
- tmpx := x - mx;
- tmpy := y - my;
- cosa := cos(angle * DEGTORAD);
- sina := sin(angle * DEGTORAD);
- x := round(tmpx * cosa - tmpy * sina) + mx;
- y := round(tmpx * sina + tmpy * cosa) + my;
- end;
-
- {----------------------------------------------------------------}
- (* transform two line points: scale, rotate and translate
- *)
- procedure xfmlinepts (var x1, y1, x2, y2 : ScaledPts;
- offh, offv : ScaledPts;
- midx, midy : ScaledPts;
- scalefact : real;
- theta : real;
- dx, dy : ScaledPts;
- sx, sy : real);
- begin
- if ((sx = 0.0) or (sy = 0.0)) then
- begin
- complain (ERRBAD);
- writeln(logfile,'?? Some scale factor is Zero... continuing anyway');
- end;
- (* scale about center of item*)
- if ((sx <> 1.0) or (sy <> 1.0)) then
- begin
- x1 := round((x1 - midx) * sx) + midx;
- x2 := round((x2 - midx) * sx) + midx;
- y1 := round((y1 - midy) * sy) + midy;
- y2 := round((y2 - midy) * sy) + midy;
- end;
- (* rotate if necessary *)
- if (theta <> 0.0) then
- begin (* rotate about the midpoint *)
- ptrotate(x1, y1, midx, midy, theta);
- ptrotate(x2, y2, midx, midy, theta);
- end;
- (* translate *)
- x1 := (x1 + round(dx * scalefact) + offh);
- x2 := (x2 + round(dx * scalefact) + offh);
- y1 := (y1 + round(dy * scalefact) + offv);
- y2 := (y2 + round(dy * scalefact) + offv);
- end; (* xfmlinepts *)
-
- {----------------------------------------------------------------}
- procedure xfmcontpts (var xpts : ControlPoints; xknots : integer;
- offh, offv : ScaledPts; midx, midy : ScaledPts;
- scalefact : real;
- theta : real; dx, dy : ScaledPts; sx, sy : real);
- var i : integer;
- begin
- (* scale about center of item *)
- if ((sx <> 1.0) or (sy <> 1.0)) then
- for i := 0 to xknots do
- begin
- xpts[i,1] := round((xpts[i,1] - midx) * sx) + midx;
- xpts[i,2] := round((xpts[i,2] - midy) * sy) + midy;
- end;
-
- if (theta <> 0.0) then
- begin (* rotate about center *)
- for i := 0 to xknots do
- begin
- ptrotate (xpts[i,1], xpts[i,2], midx, midy, theta);
- end;
- end;
- (* translate *)
- for i := 0 to xknots do
- begin
- xpts[i,1] := (xpts[i,1] + round(dx * scalefact) + offh);
- xpts[i,2] := (xpts[i,2] + round(dy * scalefact) + offv);
- end;
- end; (* xfmcontpts *)
-
-
- {----------------------------------------------------------------}
- (* convert into DVI space and offset by H & V *)
- procedure dvilinepts (var x1, y1, x2, y2 : ScaledPts;
- offh, offv : ScaledPts);
- begin
- x1 := (x1 + offh);
- x2 := (x2 + offh);
- y1 := (y1 * (-1) + offv);
- y2 := (y2 * (-1) + offv);
- end;
-
- {----------------------------------------------------------------}
- (* convert into DVI space and offset by H & V *)
- procedure dvicontpts (var xpts : ControlPoints; xknots : integer;
- offh, offv : ScaledPts);
- var i : integer;
- begin
- for i := 0 to xknots do
- begin
- xpts[i,1] := (xpts[i,1] + offh);
- xpts[i,2] := (xpts[i,2] * (-1) + offv);
- end;
- end;
-
- {----------------------------------------------------------------}
- (* transform all the figure's elements according to the
- top-level tranformation requirements in 1st Quadrant space.
- then reset the toplevel's xfms.
- *)
- procedure toplevelxfm (toplev, curfig : pItem; recurlevel : integer);
- var pi : pItem;
- null1, null2 : ScaledPts;
- old1, old2 : ScaledPts;
- midx, midy : ScaledPts;
- begin
- with toplev^ do
- begin
- midy := (BBty - BBby) div 2;
- midx := (BBrx - BBlx) div 2;
- end;
- pi := curfig^.body^.things; { if recur==0, this is same as toplev }
- while (pi <> nil) do
- begin
- with pi^ do
- begin
- case (kind) of
- Aline : begin
- xfmlinepts (lx1, ly1, lx2, ly2, 0, 0, midx, midy, 1.0,
- toplev^.figtheta, toplev^.fdx, toplev^.fdy,
- toplev^.fsx, toplev^.fsy);
- end;
- Aspline : begin
- xfmcontpts (spts, nsplknots, 0, 0, midx, midy, 1.0,
- toplev^.figtheta, toplev^.fdx, toplev^.fdy,
- toplev^.fsx, toplev^.fsy);
- end;
- Attspline : begin
- xfmcontpts (ttpts, nttknots, 0, 0, midx, midy, 1.0,
- toplev^.figtheta, toplev^.fdx, toplev^.fdy,
- toplev^.fsx, toplev^.fsy);
- end;
- Aarc : begin
- null1 := 0; null2 := 0;
- old1 := acentx; old2 := acenty;
- xfmlinepts (acentx, acenty, null1, null2, 0,0, midx, midy, 1.0,
- toplev^.figtheta, toplev^.fdx, toplev^.fdy,
- toplev^.fsx, toplev^.fsy);
-
- xfmcontpts (arcpts, narcknots + 1, 0, 0, old1, old2, 1.0,
- toplev^.figtheta,
- toplev^.fdx + (acentx - old1),
- toplev^.fdy + (acenty - old2),
- toplev^.fsx, toplev^.fsy);
- end;
- Alabel : begin
- null1 := 0; null2 := 0;
- xfmlinepts (labx, laby, null1, null2, 0, 0, midx, midy, 1.0,
- toplev^.figtheta, toplev^.fdx, toplev^.fdy,
- toplev^.fsx, toplev^.fsy);
- end;
- Abeam : ; (* not transformable *)
-
- Atieslur: ; (* not transformable *)
-
- Afigure : begin
- toplevelxfm (toplev, pi, recurlevel + 1);
- end;
- end; (* case *)
- end; (* with *)
- pi := pi^.nextitem;
- end; (* while *)
- if (recurlevel = 0) then
- begin (* reset the toplevel's xfms *)
- with toplev^ do
- begin
- figtheta := 0.0;
- fsx := 1.0; fsy := 1.0;
- fdx := 0; fdy := 0;
- end;
- end;
- end;
-
-
- {----------------------------------------------------------------}
- function scalefitfactor (actualwid, actualht,
- goalwid, goalht: ScaledPts): real;
- var sx, sy : real;
- begin
- sx := goalwid/actualwid;
- sy := goalht/actualht;
- if (sx < sy) then
- scalefitfactor := sx
- else
- scalefitfactor := sy;
- end;
-
-
-
- (* ---- The handlers for each primitive ----
- * The result of calling each handler is either immediate
- * output to the buffer of the commands to produce the
- * primitive, OR the primitive gets pushed onto a stack/list
- * that defines a current 'figure' (set of prims) for
- * output at a later time
- *
- * Look at linehandle for a basic idea of how the handlers
- * work. the others follow pretty closely.
- *)
-
-
- {------------------------------------------------------------}
- procedure linehandle (figdepth : integer; scalefact: real;
- x1, y1, x2, y2 : ScaledPts;
- dvih, dviv : ScaledPts; (* possible dvi-offsets *)
- thk : VThickness; vk : VectKind;
- patt : LineStyle;
- minx, maxx, miny, maxy : ScaledPts;
- tx, ty: ScaledPts; sx, sy, r : real);
- var midx, midy : ScaledPts;
- lineitem : pItem;
- begin
- midx := (minx + maxx) div 2;
- midy := (miny + maxy) div 2;
-
- (* do local primitive -level transformations *)
- xfmlinepts (x1, y1, x2, y2, dvih, dviv,
- midx, midy, scalefact, r, tx, ty, sx, sy);
-
- E_O_F
- else
- echo "will not over write ./src/textyl.pas.ad"
- fi
- chmod 644 ./src/textyl.pas.ad
- if [ `wc -c ./src/textyl.pas.ad | awk '{printf $1}'` -ne 30107 ]
- then
- echo `wc -c ./src/textyl.pas.ad | awk '{print "Got " $1 ", Expected " 30107}'`
- fi
- echo "Finished archive 6 of 9"
- exit
-